import * as vscode from 'vscode';
import * as os from 'os';
import { MagicApiClient, MagicServerConfig } from '../magicApiClient';
import { MirrorMeta } from './types';

/**
 * 镜像工作区工具类
 * 处理工作区相关的通用操作
 */
export class MirrorWorkspaceUtils {
    // 判断当前工作区是否为镜像工作区
    public async isMirrorWorkspace(folder: vscode.Uri): Promise<boolean> {
        if("file" === folder.scheme) {
            try {
                const metaUri = vscode.Uri.joinPath(folder, '.magic-api-mirror.json');
                await vscode.workspace.fs.stat(metaUri);
                return true;
            } catch {
                return false;
            }
        }
        return false;
    }

    // 根据连接信息在工作区内查找对应的镜像根目录
    public async findMirrorRootByConnection(roots: vscode.Uri[], conn: { url?: string; token?: string; username?: string; password?: string; lspPort?: number; debugPort?: number; }): Promise<vscode.Uri | null> {
        const normUrl = (u?: string) => (u || '').replace(/\/$/, '');
        const targetUrl = normUrl(conn.url);
        for (const root of roots) {
            const meta = await this.readMirrorMeta(root);
            if (!meta) continue;
            const metaUrl = normUrl(meta.url);
            if (targetUrl && metaUrl === targetUrl) {
                const tokenOk = !conn.token || conn.token === (meta as any).token;
                const basicOk = (!conn.username && !conn.password) || (conn.username === (meta as any).username && conn.password === (meta as any).password);
                if (tokenOk && basicOk) return root;
            }
        }
        return null;
    }

    // 提示创建镜像工作区（当连接到服务器但当前不是镜像时）
    public async promptCreateMirrorWorkspaceIfNeeded(client: MagicApiClient, serverConfig: MagicServerConfig): Promise<boolean> {
        const folders = vscode.workspace.workspaceFolders;
        const currentFolder = folders && folders.length > 0 ? folders[0].uri : null;
        // 检查当前工作区是否已经是镜像工作区，如果是则不提示
        if (currentFolder && currentFolder.scheme === "file") {
            const isMirror = await this.isMirrorWorkspace(currentFolder);
            if (isMirror) {
                return false; // 已经是镜像工作区，不需要提示
            }
        }
        if (!currentFolder || currentFolder.scheme !== "magic-api") {
            return false;
        }
        const action = await vscode.window.showInformationMessage(
            '是否创建对应的本地镜像工作区以进行本地维护？',
            '创建镜像工作区', '稍后'
        );
        if (action === '创建镜像工作区') {
            await this.createMirrorWorkspace(client, serverConfig);
            return true;
        }
        return false;
    }

    // 创建镜像工作区
    private async createMirrorWorkspace(client: MagicApiClient, serverConfig: MagicServerConfig): Promise<void> {
        // 获取当前用户home目录
        const defaultUri = vscode.Uri.file(os.homedir());
        const picked = await vscode.window.showOpenDialog({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, openLabel: '选择镜像工作区根目录', defaultUri });

        // 将选定目录作为镜像根写入连接信息并同步
        try {
            const folder = picked && picked.length > 0 ? picked[0] : undefined;
            if (!folder) return;
            // 在选定目录写入镜像元数据，并以该目录作为根（而不是 globalStorage）
            const baseMeta: MirrorMeta = {
                createdAt: Date.now(),
                url: serverConfig?.url,
                token: serverConfig?.token,
                username: serverConfig?.username,
                password: serverConfig?.password,
                lspPort: (serverConfig as any)?.lspPort,
                debugPort: (serverConfig as any)?.debugPort,
            };
            await vscode.window.withProgress({
                location: vscode.ProgressLocation.Notification,
                title: '创建镜像工作区',
                cancellable: false
            }, async (progress) => {
                progress.report({ message: '写入镜像元数据' });
                await this.writeMirrorMeta(folder, baseMeta);
                // 刷新写入本地补全用的工作台数据
                progress.report({ message: '拉取工作台补全数据' });
                await this.refreshWorkbenchCompletionData(client, folder, progress);
                // 全量同步到选定目录
                progress.report({ message: '同步服务器资源与脚本' });
                await this.syncFromServer(client, folder, serverConfig, progress);
                progress.report({ message: '打开镜像工作区（当前窗口）' });
                const curFolders = vscode.workspace.workspaceFolders;
                const nameFromCfg = serverConfig?.url ? `Mirror: ${new URL(serverConfig.url).host}` : 'Magic API Mirror';
                const replaced = curFolders && curFolders.length > 0
                    ? vscode.workspace.updateWorkspaceFolders(0, curFolders.length, { uri: folder, name: nameFromCfg })
                    : false;
                if (!replaced) {
                    // 无活动工作区时，回退到 openFolder（保持不新开窗口）
                    await vscode.commands.executeCommand('vscode.openFolder', folder, { forceNewWindow: false });
                }

                // 启动镜像监听，确保当前窗口即可进行推送/同步
                try {
                    const disposables = this.startMirrorListeners(client, folder);
                    // 需要获取extension context来添加disposables
                } catch(e) {console.warn(e)}
            });
        } catch (e) {
            vscode.window.showErrorMessage(`创建镜像工作区失败: ${String(e)}`);
        }
    }

    // 辅助方法：需要从外部提供或导入
    private async readMirrorMeta(folder: vscode.Uri): Promise<MirrorMeta | null> {
        try {
            const metaUri = vscode.Uri.joinPath(folder, '.magic-api-mirror.json');
            const buf = await vscode.workspace.fs.readFile(metaUri);
            const text = Buffer.from(buf).toString('utf8');
            return JSON.parse(text);
        } catch {
            return null;
        }
    }

    private async writeMirrorMeta(root: vscode.Uri, meta: MirrorMeta): Promise<void> {
        const dirUri = root;
        await this.ensureDir(dirUri);
        const metaUri = vscode.Uri.joinPath(root, '.magic-api-mirror.json');
        await vscode.workspace.fs.writeFile(metaUri, Buffer.from(JSON.stringify(meta, null, 2), 'utf8'));
    }

    private async refreshWorkbenchCompletionData(client: MagicApiClient, root: vscode.Uri, progress?: vscode.Progress<{ message?: string; increment?: number }>): Promise<void> {
        throw new Error('refreshWorkbenchCompletionData 需要实现或从 syncManager 导入');
    }

    private async syncFromServer(client: MagicApiClient, root: vscode.Uri, serverConfig?: MagicServerConfig, progress?: vscode.Progress<{ message?: string; increment?: number }>): Promise<void> {
        throw new Error('syncFromServer 需要实现或从 syncManager 导入');
    }

    private startMirrorListeners(client: MagicApiClient, folder: vscode.Uri): vscode.Disposable[] {
        throw new Error('startMirrorListeners 需要实现或从 listenerManager 导入');
    }

    private async ensureDir(uri: vscode.Uri): Promise<void> {
        try {
            await vscode.workspace.fs.stat(uri);
        } catch {
            await vscode.workspace.fs.createDirectory(uri);
        }
    }
}